

import it.sauronsoftware.base64.Base64;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 加解密工具类
 * 
 * @author Yichou
 *
 * <p>创建日期：2013-4-26 10:19:29</p>
 */
public final class CipherUtils {
	// 十六进制下数字到字符的映射数组
	private final static char[] hexDigitsChr = { 
		'0', '1', '2', '3', '4', '5', 
		'6', '7', '8', '9', 'a', 'b', 
		'c', 'd', 'e', 'f' 
	};

//	private static String byteArrayToHexString(byte[] b) {
//		StringBuffer resultSb = new StringBuffer();
//		char[] chr = new char[2];
//		
//		for (int i = 0; i < b.length; i++) {
//			byteToHexString(b[i], chr);
//		}
//		
//		return resultSb.toString();
//	}
//
//	private static void byteToHexString(byte b, char[] out) {
//		int n = b<0? 0xff+b : b;
//		out[0] = hexDigitsChr[n / 0x0A];
//		out[1] = hexDigitsChr[n % 0x0A];
//	}
	
	/**
	 * 计算MD5
	 * 
	 * @param args
	 * @return
	 */
	public static String getMd5String(byte args[]){
		// 使用MD5创建MessageDigest对象
		MessageDigest mdTemp;
		try {
			mdTemp = MessageDigest.getInstance("MD5");
			mdTemp.update(args);
			
			byte[] md = mdTemp.digest();
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			
			for (int i = 0; i < j; i++) {
				byte b = md[i];
				
				// 将没个数(int)b进行双字节加密
				str[k++] = hexDigitsChr[b >> 4 & 0xf];
				str[k++] = hexDigitsChr[b & 0xf];
			}
			
			return new String(str);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
     * 对称解密算法
     * 
     * @param s
     * @param key1
     * @param key2
     * 
     * @return
     */
    public static String decrypt(String s) {
    	int key1 = 8389;
    	int key2 = 84322;
    			
		String str = "";
		try {
			//base64解密
			//byte[] codse = Base64.decode(s.getBytes());
			//String code = new String(codse, "UTF-8");
				
			String code = s;
				
//			if (code.length() % 2 != 0) {
//				return null;
//			}
			
			StringBuffer sb = new StringBuffer(code);
			ByteBuffer bb = ByteBuffer.allocate(code.length() / 2);

			int i = 0;
			while (i < code.length()) {
				bb.put((byte) ((Integer.parseInt(sb.substring(i, i + 1), 16)) << 4 | Integer
						.parseInt(sb.substring(i + 1, i + 2), 16)));
				i = i + 2;
			}
			
			byte cCode[] = bb.array();
			
			for (i = 0; i < cCode.length; i++) {
				if (i == cCode.length - 1) {
					cCode[cCode.length - 1] ^= (key2 % 128);
				} else if (cCode[i] != cCode[i + 1]) {
					cCode[i] ^= cCode[i + 1];
				}
			}
			for (i = cCode.length - 1; i >= 0; i--) {
				if (i == 0) {
					cCode[0] ^= (key1 % 128);
				} else if (cCode[i] != cCode[i - 1]) {
					cCode[i] ^= cCode[i - 1];
				}
			}
			
			str = new String(cCode, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return str;
	}
    
    /**
	 * @param s
	 * @param k1
	 * @param k2
	 * 
	 * @return
	 */
	public static String encrypt( String s ) {
    	int k1 = 8389;
    	int k2 = 84322;
		byte[] _s = s.getBytes();
		int strLen = _s.length;
		int i = 0;
		
		for (i = 0; i < strLen; i++) {
			if (0 == i) {
				_s[0] ^= (k1 % 128);
			} else if (_s[i] != _s[i - 1]) {
				_s[i] ^= _s[i - 1];
			}
		}
		
		int j = strLen - 1;
		for (i = j; i > -1; i--) {
			if (i == j) {
				_s[i] ^= (k2 % 128);
			} else if (_s[i] != _s[i + 1]) {
				_s[i] ^= _s[i + 1];
			}
		}
		String result = "";
		for (i = 0; i < strLen; i++) {
			result += Integer.toHexString((0x000000ff & _s[i]) | 0xffffff00)
					.substring(6);			
		}
		
		return result;
	}

	/**
	 * 计算base64
	 * 
	 * @param args
	 * @return
	 */
	public static String getDecB64String(byte args[]){
		//base64解密
		byte[] codse = Base64.decode(args);
		
		try {
			return new String(codse, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
}
